/*---------------------------------------------------------------------------------


  - WinterMute <wntrmute@gmail.com>
  http://www.devkitpro.org
---------------------------------------------------------------------------------*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/param.h>


char	srcName[MAXPATHLEN], dstName[MAXPATHLEN];	// file name buffers
static char	baseFileName[MAXPATHLEN];		// source file name without extension
static char	ArrayName[MAXPATHLEN];		// source file name without extension

//---------------------------------------------------------------------------------
// Parse file name. Put file name without extension in
// baseFileName, and return:
//---------------------------------------------------------------------------------
void parseFileName(char *str) {
//---------------------------------------------------------------------------------
	int	i;
	char	*cptr;


	strcpy(baseFileName, str);
	strcpy(srcName, str);


	cptr = strrchr(str, '.');
	if (!cptr) {						// if '.' not found, then append default extension
		strcat(srcName, ".bin");
	}
	else {
		i = (int) (cptr - str);	// get offset of '.' character
		baseFileName[i] = '\0';
	}

	if ((cptr = strrchr(baseFileName,'\\'))) {
		strcpy(ArrayName, cptr+1);
	} else if ((cptr = strrchr(baseFileName, '/'))) {
		strcpy(ArrayName, cptr+1);
	} else {
		strcpy(ArrayName, baseFileName);
	}

}

//---------------------------------------------------------------------------------
long fsize(FILE* f) {
//---------------------------------------------------------------------------------
	long size;
	long temp = ftell(f);

	fseek(f,0,SEEK_END);

	size = ftell(f);

	fseek(f, temp, SEEK_SET);

	return size;
}


static const char head[] = "/*\n  This file was autogenerated by raw2c.\nVisit http://www.devkitpro.org\n*/\n\n";
static const char comment[] = "//---------------------------------------------------------------------------------\n";

void Help() {}

//---------------------------------------------------------------------------------
void usage () {
//---------------------------------------------------------------------------------
	fprintf(stderr,	"Usage:\traw2c filename<ext>\n"
					"\tConverts a binary file to C array and header\n"
					"\tdefault input extension is .bin\n");
}

//---------------------------------------------------------------------------------
static void MakeSource(FILE* Infile, FILE* Outfile, FILE *Headerfile, int size) {
//---------------------------------------------------------------------------------

	unsigned long int counter = 0UL;
	unsigned long int length;
	unsigned char thisElement;
	rewind(Infile);
	rewind(Outfile);
	length = fsize(Infile);

	fprintf(Headerfile, head); /* Put top comment into source */
	fprintf(Headerfile, comment); /* Put separator comment into source */
	fprintf(Headerfile, "#ifndef _%s_h_\n",ArrayName);
	fprintf(Headerfile, "#define _%s_h_\n",ArrayName);
	fprintf(Headerfile, comment); /* Put separator comment into source */
	fprintf(Headerfile, "extern const unsigned char %s[];\n",ArrayName);
	fprintf(Headerfile, "extern const int %s_size;\n",ArrayName);
	fprintf(Headerfile, comment); /* Put separator comment into source */
	fprintf(Headerfile, "#endif //_%s_h_\n",ArrayName);
	fprintf(Headerfile, comment); /* Put separator comment into source */

	fprintf(Outfile, head); /* Put top comment into source */
	fprintf(Outfile, "const unsigned char %s[] = {\n\t", ArrayName);

	while ( counter < length ) {


		if ( fread(&thisElement, 1, 1, Infile) >= 1 ) {
			fprintf(Outfile,"0x%02x", thisElement);
		}

		counter++;
		if ( counter < length ) /* More to go */
 		fprintf(Outfile, ", ");

		if ( !((counter) % 16) ) {
			fputc('\n', Outfile);
			fputc('\t', Outfile);
		}

	}

	fprintf(Outfile, "\n};\n");
	fprintf(Outfile,"const int %s_size = sizeof(%s);\n",ArrayName,ArrayName);
	return;
}

//---------------------------------------------------------------------------------
int main (int argc, char* argv[]) {
//---------------------------------------------------------------------------------
	int elementSize;
	int a;

	FILE *fInfile, *fCfile, *fHfile;

	fprintf(stderr,"Raw2C by WinterMute\n");
	if (argc < 2) {
		usage();
		return -1;
	}
	for (a=1; a<argc; a++) {

		if (argv[a][0] == '-')
		{
			switch (argv[a][1])
			{
				case 'h':
					Help();
					break;
				case 's':
					elementSize = atoi(&argv[a][2]);
					break;
				default:
				{
					printf("Unknown option: %s\n", argv[a]);
					Help();
					break;
				}
			}
		} else {
			parseFileName(argv[a]);
		}
	}

	fInfile = fopen(srcName, "rb");

	strcpy(dstName, ArrayName);
	strcat(dstName, ".c");
	fCfile = fopen(dstName, "wb");

	strcpy(dstName, ArrayName);
	strcat(dstName, ".h");
	fHfile = fopen(dstName, "wb");

	MakeSource(fInfile,fCfile,fHfile,1);

	fclose(fInfile);
	fclose(fCfile);
	fclose(fHfile);


	return EXIT_SUCCESS;
}


